package com.dbdeploy.database.changelog; import com.dbdeploy.scripts.ChangeScript; import org.hamcrest.Matchers; import static org.hamcrest.Matchers.equalToIgnoringWhiteSpace; import static org.hamcrest.Matchers.hasItems; import static org.junit.Assert.assertThat; import org.junit.Before; import org.junit.Test; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.startsWith; import org.mockito.Mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.MockitoAnnotations; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Date; import java.util.List; public class DatabaseSchemaVersionManagerTest { private final ChangeScript script = new ChangeScript(99, "Some Description"); private DatabaseSchemaVersionManager schemaVersionManager; @Mock private ResultSet expectedResultSet; @Mock private QueryExecuter queryExecuter; @Mock private DatabaseSchemaVersionManager.CurrentTimeProvider timeProvider; @Before public void setUp() throws SQLException { MockitoAnnotations.initMocks(this); when(queryExecuter.executeQuery(anyString())).thenReturn(expectedResultSet); schemaVersionManager = new DatabaseSchemaVersionManager(queryExecuter, "changelog"); schemaVersionManager.setTimeProvider(timeProvider); } @Test public void shouldUseQueryExecuterToReadInformationFromTheChangelogTable() throws Exception { when(expectedResultSet.next()).thenReturn(true, true, true, false); when(expectedResultSet.getLong(1)).thenReturn(5L, 9L, 12L); final List<Long> numbers = schemaVersionManager.getAppliedChanges(); assertThat(numbers, hasItems(5L, 9L, 12L)); } @Test public void shouldUpdateChangelogTable() throws Exception { Date now = new Date(); when(queryExecuter.getDatabaseUsername()).thenReturn("DBUSER"); when(timeProvider.now()).thenReturn(now); schemaVersionManager.recordScriptApplied(script); String expected = "INSERT INTO changelog (change_number, complete_dt, applied_by, description) " + "VALUES (?, ?, ?, ?)"; verify(queryExecuter).execute(expected, script.getId(), new Timestamp(now.getTime()), "DBUSER", script.getDescription()); } @Test public void shouldGenerateSqlStringToDeleteChangelogTableAfterUndoScriptApplication() throws Exception { String sql = schemaVersionManager.getChangelogDeleteSql(script); String expected = "DELETE FROM changelog WHERE change_number = 99"; assertThat(sql, equalToIgnoringWhiteSpace(expected)); } @Test public void shouldGetAppliedChangesFromSpecifiedChangelogTableName() throws SQLException { DatabaseSchemaVersionManager schemaVersionManagerWithDifferentTableName = new DatabaseSchemaVersionManager(queryExecuter, "user_specified_changelog"); schemaVersionManagerWithDifferentTableName.getAppliedChanges(); verify(queryExecuter).executeQuery(startsWith("SELECT change_number FROM user_specified_changelog ")); } @Test public void shouldGenerateSqlStringContainingSpecifiedChangelogTableNameOnDelete() { DatabaseSchemaVersionManager schemaVersionManagerWithDifferentTableName = new DatabaseSchemaVersionManager(queryExecuter, "user_specified_changelog"); String updateSql = schemaVersionManagerWithDifferentTableName.getChangelogDeleteSql(script); assertThat(updateSql, Matchers.startsWith("DELETE FROM user_specified_changelog ")); } }